package com.sun.lib.net;

import android.app.Application;
import android.graphics.Bitmap;
import android.text.TextUtils;

import com.google.gson.Gson;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.cache.CacheMode;
import com.lzy.okgo.convert.BitmapConvert;
import com.lzy.okgo.convert.StringConvert;
import com.lzy.okgo.model.HttpHeaders;
import com.lzy.okgo.model.HttpParams;
import com.lzy.okgo.request.GetRequest;
import com.lzy.okgo.request.PostRequest;
import com.lzy.okrx2.adapter.ObservableResponse;
import com.orhanobut.logger.Logger;
import com.sun.lib.util.MD5Utils;

import java.io.File;
import java.util.HashMap;

import io.reactivex.Observable;
import io.reactivex.annotations.NonNull;
import okhttp3.OkHttpClient;

/*
 * Created by Administrator on 2019/7/23.
 *
 * #                                                   #
 * #                       _oo0oo_                     #
 * #                      o8888888o                    #
 * #                      88" . "88                    #
 * #                      (| -_- |)                    #
 * #                      0\  =  /0                    #
 * #                    ___/`---'\___                  #
 * #                  .' \\|     |# '.                 #
 * #                 / \\|||  :  |||# \                #
 * #                / _||||| -:- |||||- \              #
 * #               |   | \\\  -  #/ |   |              #
 * #               | \_|  ''\---/''  |_/ |             #
 * #               \  .-\__  '-'  ___/-. /             #
 * #             ___'. .'  /--.--\  `. .'___           #
 * #          ."" '<  `.___\_<|>_/___.' >' "".         #
 * #         | | :  `- \`.;`\ _ /`;.`/ - ` : | |       #
 * #         \  \ `_.   \_ __\ /__ _/   .-` /  /       #
 * #     =====`-.____`.___ \_____/___.-`___.-'=====    #
 * #                       `=---='                     #
 * #     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   #
 * #                                                   #
 * #               佛祖保佑         永无BUG              #
 * #                                                   #
 */
public class DataManager {
    private HttpHeaders headers;
    private HttpParams params;
    private boolean isInit = false;
    private Application context;

    public static DataManager getInstance() {
        return DataManagerHolder.holder;
    }

    private static class DataManagerHolder {
        private static DataManager holder = new DataManager();
    }

    private DataManager() {
        headers = new HttpHeaders();
        params = new HttpParams();
    }

    public void init(Application context) {
        if (isInit) return;
        this.context = context;
        isInit = true;
        initOkGo();
    }

    private void initOkGo() {
        OkGo.getInstance().init(context)
                .setOkHttpClient(new OkHttpClient().newBuilder().build())
                .setRetryCount(1);
    }

    private void getPublicHeader(){
        headers.clear();
        // TODO 添加默认header
    }

    public void addPublicHeaders(HttpHeaders headers){
        this.headers.put(headers);
    }

    public void addPublicParams(HttpParams params){
        this.params.put(params);
    }

    public Observable post(@NonNull String url, HashMap<String,String> params, HttpHeaders headers, boolean toJson){
        getPublicHeader();
        PostRequest<String> request = OkGo.<String>post(url);
        request.headers(this.headers);
        if (headers != null) {
            request.headers(headers);
        }
        if (request.getHeaders() != null) {

            StringBuilder sb = new StringBuilder();
            for (String key : request.getHeaders().getNames()) {
                sb.append(key + "===" + request.getHeaders().get(key) + "\n");
            }
            Logger.d("url:" + url + "\nheaders:\n" + sb.toString());
        }
        if (params != null && !params.isEmpty()) {
            if (toJson) {
                String json = new Gson().toJson(params);
                if (!TextUtils.isEmpty(json)) {
                    Logger.json(json);
                    request.upJson(json);
                }
            } else {
                request.params(params);
            }
            StringBuilder sb = new StringBuilder();
            for (String key : params.keySet()) {
                sb.append(key + "===" + params.get(key) + "\n");
            }
            Logger.d("url:\n" + url);
            Logger.d("params:\n" + sb.toString());

        }

        request.converter(new StringConvert());
        return request.adapt(new ObservableResponse<>());
    }

    public Observable post(@NonNull String url, HashMap<String, String> params) {
        return post(url, params, null, false);
    }

    public Observable getBitmap(String url) {
        GetRequest<Bitmap> getRequest = OkGo.get(url);
        getRequest.converter(new BitmapConvert());
        return getRequest.adapt(new ObservableResponse<>());
    }

    public Observable get(@NonNull String url, HttpDatas params, HttpHeaders headers, String cacheKey, CacheMode mode) {
        getPublicHeader();
        GetRequest<String> getRequest = OkGo.<String>get(url);
        getRequest.headers(this.headers);
        if (headers != null)
            getRequest.headers(headers);
        //打印当前headers
        if (getRequest.getHeaders() != null) {

            StringBuilder sb = new StringBuilder();
            for (String key : getRequest.getHeaders().getNames()) {
                sb.append(key + "===" + getRequest.getHeaders().get(key) + "\n");
            }
            Logger.d("url:" + url + "\nheaders:\n" + sb.toString());
        }
        if (params != null && !params.isEmpty()) {
            getRequest.params(params);
            Logger.d("params:\n" + params.toJSONString());
        }
        if (mode != null) {
            getRequest.cacheMode(mode);
            if (!TextUtils.isEmpty(cacheKey))
                getRequest.cacheKey(cacheKey);
        }

        getRequest.converter(new StringConvert());
        return getRequest.adapt(new ObservableResponse<>());
    }

    public Observable get(@NonNull String url, HttpDatas params, CacheMode mode) {
        return get(url, params, null, null, mode);
    }

    public Observable get(String url, HttpDatas params, HttpHeaders headers, CacheMode mode) {
        return get(url, params, headers, null, mode);
    }

    public Observable get(@NonNull String url, HttpDatas params, HttpHeaders headers) {
        return get(url, params, headers, null, null);
    }

    public Observable get(@NonNull String url, HttpDatas params) {
        return get(url, params, null, null, null);
    }

    public Observable get(String url) {
        return get(url, null);
    }


    public Observable getCache(String url, HttpDatas params) {
        getPublicHeader();
        GetRequest<String> getRequest = OkGo.<String>get(url);
        getRequest.headers(this.headers);
        if (headers != null)
            getRequest.headers(headers);
        //打印当前headers
        if (getRequest.getHeaders() != null) {

            StringBuilder sb = new StringBuilder();
            for (String key : getRequest.getHeaders().getNames()) {
                sb.append(key + "===" + getRequest.getHeaders().get(key) + "\n");
            }
            Logger.d("url:" + url + "\nheaders:\n" + sb.toString());
        }
        if (params != null && !params.isEmpty()) {
            getRequest.params(params);
            Logger.d("params:\n" + params.toJSONString());
            getRequest.cacheKey(MD5Utils.md5(url+"_"+headers.toString()+"_"+params.toString()));
        }else {
            getRequest.cacheKey(MD5Utils.md5(url + "_" + headers.toString()));
        }
        getRequest.cachePolicy(new OnlyCacheRequestCachePolicy<>(getRequest));

        getRequest.converter(new StringConvert());
        return getRequest.adapt(new ObservableResponse<>());
    }


    public GetRequest<File> download(String url) {
        GetRequest<File> getRequest = OkGo.get(url);
        return getRequest;
    }
}
